package com.ruoyi.point.watcher.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.point.pojo.OperationLog;
import com.ruoyi.point.pojo.Picker;
import com.ruoyi.framework.pojo.VirInfo;
import com.ruoyi.point.service.IOperationLogService;
import com.ruoyi.point.service.IPickerService;
import com.ruoyi.point.service.ISessionPermissionsService;
import com.ruoyi.framework.point.PointTable;
import com.ruoyi.point.utils.Constants;
import com.ruoyi.framework.watcher.IWatcher;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Component
public class PickerWatcher implements IWatcher {

    @Autowired
    private PointTable pointTable;
    @Autowired
    private RedisCache cache;

    @Autowired
    private ISessionPermissionsService sessionPermissionsService;

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().registerModule(new JavaTimeModule());

    @Autowired
    private IPickerService pickerService;

    @Autowired
    private IOperationLogService operationLogService;

    private static final String NAME_INFO = "Picker";

    @PostConstruct
    public void init() {
        pointTable.addReadWatcher(NAME_INFO,this);
        pointTable.addWriteWatcher(NAME_INFO,this);
    }

    @Override
    @Async
    public List<? extends VirInfo> selectPointInfo(String key,String parameter,Object value) throws RuntimeException {
        String[] split = parameter.split("\\.");
        String parameters = split[0].replace("$", "");
        if (parameters.equals("all")){
            return pickerService.selectPickerList(null);
        } else {
            Picker picker = new Picker();
            picker.setPickerId(Long.valueOf(parameters));
            return pickerService.selectPickerList(picker);
        }
    }

    @Override
    @Async
    @Transactional
    public void updatePointTableValue(String key, Object value) {
        String[] split = key.split("\\.");
        String id = split[1].replace("$", "");
        JsonNode jsonObject = null;
        String userId = null;
        if (cache.getCacheObject("Scepter") == null) {
            throw new RuntimeException("There is no staff at present and cannot control it.Please apply for a scepter");
        }
        try {
            userId = split[3];
            if (cache.getCacheObject("Scepter") != Long.valueOf(userId)){
                throw new RuntimeException("Currently, you are not a staff member and cannot operate.Please apply for a scepter");
            }
            String param = split[2];
            Picker picker = pickerService.selectPickerByPickerId(Long.valueOf(id));
            if (picker != null) {
                value = value.toString().substring(1, value.toString().length() - 1);
//                operationManual(split[0],picker.getPickerId(),value, Long.valueOf(userId));
                BeanUtils.setProperty(picker,param,value);
                pickerService.updatePicker(picker);
            } else {
                throw new RuntimeException("No current Device");
            }
        } catch (ArrayIndexOutOfBoundsException | IllegalAccessException | InvocationTargetException e) {
            userId = split[2];
            if (cache.getCacheObject("Scepter") != Long.valueOf(userId)){
                throw new RuntimeException("Currently, you are not a staff member and cannot operate.Please apply for a scepter");
            }
            try {
                jsonObject = OBJECT_MAPPER.readTree(value.toString());
                Picker picker = OBJECT_MAPPER.readValue(jsonObject.traverse(),Picker.class);
                pickerService.updatePicker(picker);
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            }
        }
    }

    @Transactional
    public void operationManual(String key,Long pickerId,Object value,Long userId){
        Picker picker = pickerService.selectPickerByPickerId(pickerId);
        switch (key){
            case "currentX":
                Long aLong1 = picker.getCurrentX() + (Long) value;
                if (aLong1 > picker.getCurrentX()) {
                    operationLogService.insertOperationLog(OperationLog
                            .builder()
                            .createTime(LocalDateTime.now())
                            .operationMessage(Constants.USER_TAP + "前进" + Constants.BUTTON)
                            .operationUser(userId)
                            .pickerId(pickerId)
                            .build());
                    operationLogService.insertOperationLog(OperationLog
                            .builder()
                            .createTime(LocalDateTime.now())
                            .operationMessage("前进" + Constants.START_INFO)
                            .operationUser(userId)
                            .pickerId(pickerId)
                            .build());
                    operationLogService.insertOperationLog(OperationLog
                            .builder()
                            .createTime(LocalDateTime.now())
                            .operationMessage(Constants.TONGS_INFO + "前进" + value + Constants.CM)
                            .operationUser(userId)
                            .pickerId(pickerId)
                            .build());
                    picker.setCurrentX(aLong1);
                    if (pickerService.updatePicker(picker) > 0) {
                        operationLogService.insertOperationLog(OperationLog
                                .builder()
                                .createTime(LocalDateTime.now())
                                .operationMessage(Constants.TONGS_INFO + "前进" + Constants.OPERATION_SUCCESS)
                                .operationUser(userId)
                                .pickerId(pickerId)
                                .build());
                    } else {
                        operationLogService.insertOperationLog(OperationLog
                                .builder()
                                .createTime(LocalDateTime.now())
                                .operationMessage(Constants.TONGS_INFO + "前进" + Constants.OPERATION_ERROR)
                                .operationUser(userId)
                                .pickerId(pickerId)
                                .build());
                    }
                } else if (aLong1 < picker.getCurrentX() && aLong1 > 0) {
                    operationLogService.insertOperationLog(OperationLog
                            .builder()
                            .createTime(LocalDateTime.now())
                            .operationMessage(Constants.USER_TAP + "后退" + Constants.BUTTON)
                            .operationUser(cache.getCacheObject("Scepter"))
                            .pickerId(pickerId)
                            .build());
                    operationLogService.insertOperationLog(OperationLog
                            .builder()
                            .createTime(LocalDateTime.now())
                            .operationMessage("后退" + Constants.START_INFO)
                            .operationUser(userId)
                            .pickerId(pickerId)
                            .build());
                    operationLogService.insertOperationLog(OperationLog
                            .builder()
                            .createTime(LocalDateTime.now())
                            .operationMessage(Constants.TONGS_INFO + "后退" + value + Constants.CM)
                            .operationUser(userId)
                            .pickerId(pickerId)
                            .build());
                    picker.setCurrentX(aLong1);
                    if (pickerService.updatePicker(picker) > 0) {
                        operationLogService.insertOperationLog(OperationLog
                                .builder()
                                .createTime(LocalDateTime.now())
                                .operationMessage(Constants.TONGS_INFO + "后退" + Constants.OPERATION_SUCCESS)
                                .operationUser(userId)
                                .pickerId(pickerId)
                                .build());
                    } else {
                        operationLogService.insertOperationLog(OperationLog
                                .builder()
                                .createTime(LocalDateTime.now())
                                .operationMessage(Constants.TONGS_INFO + "前进" + Constants.OPERATION_ERROR)
                                .operationUser(userId)
                                .pickerId(pickerId)
                                .build());
                    }
                } else if (aLong1 < 0){
                    operationLogService.insertOperationLog(OperationLog
                            .builder()
                            .createTime(LocalDateTime.now())
                            .operationMessage(Constants.TONGS_INFO + "后退" + Constants.OPERATION_ERROR)
                            .operationUser(cache.getCacheObject("Scepter"))
                            .pickerId(pickerId)
                            .build());
                }
                break;
            case "currentY":
                break;
            case "currentZ":
                break;
            case "currentCatch":
                break;
            case "currentSuction":
                break;
            case "currentPut":
                break;
            case "currentBlow":
                break;
        }
    }


}
